package com.baizhi.service.impl;

import com.baizhi.config.redis.AddCacheAnnotation;
import com.baizhi.config.redis.DeleteCacheAnnotation;
import com.baizhi.config.log.LogAnnotation;
import com.baizhi.entity.User;
import com.baizhi.mapper.UserMapper;
import com.baizhi.service.UserService;
import com.baizhi.util.ThreadPollUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;

@Service
@Slf4j
public class UserServiceImpl<map> implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Transactional()
    @LogAnnotation(content = "用户展示",type = "select")
    @AddCacheAnnotation
    public Map selectPage(Integer pageNum, Integer pageSize, String option, String search) {
        Integer offset = (pageNum-1)*pageSize;
        log.debug(pageNum.toString());
        List<User> users = userMapper.selectPage(offset, pageSize, option, search);
        Integer count = userMapper.count(option, search);
        Map map = new HashMap();
        map.put("code",0);
        map.put("data",users);
        map.put("count",count);
        return map;
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    @LogAnnotation(content = "更新用户状态",type = "update")
    @DeleteCacheAnnotation
    public Map updateUserStatus(User user) {
        log.info(user.toString());
        Map map = new HashMap();
        if(user.getStatus()==0){
            user.setStatus(1);
        }else{
            user.setStatus(0);
        }
        try{
            userMapper.update(user);
            map.put("status","success");
        }catch(Exception e){
            map.put("status","failed");
            map.put("msg","修改失败，请稍后再试");
        }
        return map;
    }

    @Transactional()
    public User selectById(Integer id) {
        User user = userMapper.selectById(id);
        return user;
    }

    @Transactional()
    @LogAnnotation(content = "统计性别",type = "select")
    public Map manCount() {
        List<Map> maps = userMapper.manCount();
        List<String> name = new ArrayList<>();
        List<Long> value = new ArrayList<>();
        Map map = new HashMap();
        for(Map map2 : maps){
            name.add((String) map2.get("name"));
            value.add((Long) map2.get("value"));
        }
        map.put("name",name);
        map.put("value",value);
        return map;
    }
    @Transactional()
    @LogAnnotation(content = "统计注册量",type = "select")
    public Map selectWeekCount(){
        List<Map> list = userMapper.weekCount();
        List<String> week = new ArrayList<>();
        List<Long> value = new ArrayList<>();
        Map map = new HashMap();
        for(Map map2 : list){
            week.add( map2.get("week")+"");
            value.add((Long) map2.get("value"));
        }
        map.put("week",week);
        map.put("value",value);
        return map;
    }
    @Transactional()
    @LogAnnotation(content = "统计省份",type = "select")
    public List<Map> selectProvinceCount(){
        return userMapper.provinceCount();
    }
    @Transactional()
    @LogAnnotation(content = "统计用户信息",type = "select")
    public Map selectAllCount(){
        Map map = new HashMap();
        map.put("sex",manCount());
        map.put("week",selectWeekCount());
        map.put("province",selectProvinceCount());
        return map;
    }
    @Transactional()
    @LogAnnotation(content = "线程池统计用户信息",type = "select")
    @AddCacheAnnotation
    public Map selectAllCountByThread() {
        Map map = new HashMap();
//        1.创建计数器
        CountDownLatch latch = new CountDownLatch(3);
//        2.通过线程池执行三个子任务
        ThreadPoolExecutor executor = ThreadPollUtil.executor;
        executor.submit(new Runnable() {
            @Override
            public void run() {
                map.put("sex",manCount());
                //计数器减一
                latch.countDown();
            }
        });
        executor.submit(new Runnable() {
            @Override
            public void run() {
                map.put("week",selectWeekCount());
                //计数器减一
                latch.countDown();
            }
        });
        executor.submit(new Runnable() {
            @Override
            public void run() {
                map.put("province",selectProvinceCount());
                //计数器减一
                latch.countDown();
            }
        });
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return map;
    }
}
